/**
 * 项目名称：interface-server
 * 文件名：HttpClientServiceImpl.java
 * 版本信息：
 * 日期：2016年4月22日
 * Copyright asiainfo Corporation 2016
 * 版权所有 *
 */
package com.example.daytest.swing;

import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;


/**
 * HttpClientServiceImpl
 *
 * @version 1.0
 * @author：daijun@asiainfo.com
 * @Sep：2016年4月22日 下午2:07:58
 */
public class HttpClientUtils {
    private static final Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);

    public static String post(String url, String content) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createMinimal();
        String body = null;
        HttpPost httpost = new HttpPost(url);
        httpost.setEntity(new ByteArrayEntity(content.getBytes("UTF-8")));
        body = invoke(httpclient, httpost);
        org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);
        return body;
    }

    public static String post(String url, String content, Header[] heads) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createMinimal();
        String body = null;
        HttpPost httpost = new HttpPost(url);
        httpost.setEntity(new ByteArrayEntity(content.getBytes("UTF-8")));
        httpost.setHeaders(heads);
        body = invoke(httpclient, httpost);
        org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);
        return body;
    }

    public static String post(String url, String content, Header[] heads, int connectTmeout, int socketTimeout) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createMinimal();
        String body = null;
        RequestConfig requestConfig = newRequestConfig(connectTmeout);
        HttpPost httpost = new HttpPost(url);
        httpost.setEntity(new ByteArrayEntity(content.getBytes("UTF-8")));
        httpost.setConfig(requestConfig);
        httpost.setHeaders(heads);
        body = invoke(httpclient, httpost);
        org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);
        return body;
    }

    public static String post(String url, String content, Header[] heads, int timeout) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createMinimal();
        String body = null;
        RequestConfig requestConfig = newRequestConfig(timeout);
        HttpPost httpost = new HttpPost(url);
        httpost.setEntity(new ByteArrayEntity(content.getBytes("UTF-8")));
        httpost.setConfig(requestConfig);
        httpost.setHeaders(heads);
        body = invoke(httpclient, httpost);
        org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);
        return body;
    }

    public static String post(String url, Map<String, String> params) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createMinimal();
        HttpPost post = postForm(url, params);
        String body = invoke(httpclient, post);
        org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);
        return body;
    }

    /**
     * 表单请求
     * @param url
     * @param params
     * @param heads
     * @param timeout
     * @return
     * @throws Exception
     */
    public static String post(String url, Map<String, String> params,Header[] heads,int timeout) throws Exception {
        HttpPost post = new HttpPost(url);
        post.setConfig(newRequestConfig(timeout));
        if(heads!=null && heads.length>0){
            post.setHeaders(heads);
        }
        if (params!=null && params.size()>0) {
            post.setEntity(newEntity(params));
        }

        CloseableHttpClient httpclient = HttpClients.createMinimal();
        try {
            return invoke(httpclient, post);
        }finally{
            org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);
        }
    }

    private static RequestConfig newRequestConfig(int timeout){
        RequestConfig.Builder builder = RequestConfig.custom();
        if (builder==null){
            throw new RuntimeException("ERROR Null");
        }
        builder.setConnectionRequestTimeout(timeout);
        builder.setSocketTimeout(timeout);
        RequestConfig config = builder.build();
        if (config==null){
            throw new RuntimeException("ERROR Null");
        }
        return config;
    }


    public static String get(String url) throws Exception {
        return get(url, null);
    }

    public static String get(String url, Map<String, Object> params) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createMinimal();
        String body = null;
        if (params != null && !params.isEmpty()) {
            List<NameValuePair> pairs = new ArrayList<>(params.size());
            for (String key : params.keySet()) {
                Object value = params.get(key);
                if (value!=null) {
                    pairs.add(new BasicNameValuePair(key, value.toString()));
                }
            }
            String param = EntityUtils.toString(new UrlEncodedFormEntity(pairs, "UTF-8"));
            url += "?" + param;
        }
        HttpGet get = new HttpGet(url);
        get.setHeader("Content-type", "UTF-8");
        get.setHeader("Connection", "close");
        body = invoke(httpclient, get);

        org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);

        return body;
    }

    public static String get(String url, Map<String, Object> params, int socketTimeout) throws Exception {

        CloseableHttpClient httpclient = HttpClients.createMinimal();

        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).build();

        String body = null;
        if (params != null && !params.isEmpty()) {
            List<NameValuePair> pairs = new ArrayList<>(params.size());
            for (String key : params.keySet()) {
                Object value = params.get(key);
                if (value!=null) {
                    pairs.add(new BasicNameValuePair(key, value.toString()));
                }
            }
            String param = EntityUtils.toString(new UrlEncodedFormEntity(pairs, "UTF-8"));
            url += "?" + param;
        }
        HttpGet get = new HttpGet(url);
        get.setConfig(requestConfig);
        get.setHeader("Content-type", "UTF-8");
        get.setHeader("Connection", "close");
        body = invoke(httpclient, get);

        org.apache.http.client.utils.HttpClientUtils.closeQuietly(httpclient);

        return body;
    }


    public static String invoke(HttpClient httpclient, HttpUriRequest httpost) {

        HttpResponse response = sendRequest(httpclient, httpost);
        String body = paseResponse(response);
        return body;
    }

    private static String paseResponse(HttpResponse response) {

        HttpEntity entity = response.getEntity();

        String body = null;
        try {
            Charset charset = null;
            ContentType contentType = ContentType.get(entity);
            if (contentType != null) {
                charset = contentType.getCharset();
            }
            if (null != charset && "ISO-8859-1".equalsIgnoreCase(charset.displayName())) {
                String content = EntityUtils.toString(entity, charset);
                if(content!=null) {
                    body = new String(content.getBytes(charset), "utf-8");
                }
            } else {
                body = EntityUtils.toString(entity, "utf-8");
            }
        } catch (ParseException e) {
            logger.error("ParseException e:{}", e);
        } catch (IOException e) {
            logger.error("IOException e:{}", e);
        } finally {
            if (response != null) {
                try {
                    EntityUtils.consume(entity);
                } catch (IOException e) {
                    logger.error("finally--IOException e:{}", e);
                } // 会自动释放连接
            }
        }
        return body;
    }

    private static HttpResponse sendRequest(HttpClient httpclient, HttpUriRequest httpost) {
        HttpResponse response = null;
        try {
            response = httpclient.execute(httpost);
        } catch (ClientProtocolException e) {
            logger.error("exception e:{}", e);
        } catch (IOException e) {
            logger.error("exception e:{}", e);
        }
        return response;
    }

    private static HttpPost postForm(String url, Map<String, String> params) {
        HttpPost httpost = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        Set<String> keySet = params.keySet();
        for (String key : keySet) {
            nvps.add(new BasicNameValuePair(key, params.get(key)));
        }
        try {
            httpost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            logger.error("exception e:{}", e);
        }
        return httpost;
    }

    private static UrlEncodedFormEntity newEntity(Map<String,String> params) throws Exception{
        List<NameValuePair> list = new ArrayList<NameValuePair>();
        for(Map.Entry<String,String> entry: params.entrySet()){
            list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        return new UrlEncodedFormEntity(list,"UTF-8");
    }
}

